<?php
class ControllerPaymentOgone extends Controller {
	public function index() {
		
		$this->language->load('payment/ogone');
		
		$this->data['button_confirm'] = $this->language->get('button_confirm');
		$this->data['text_info'] = $this->language->get('text_info');
		
		if ($this->config->get('ogone_mode') == 'live') {
			$this->data['action'] = $this->config->get('ogone_action_live');
		} elseif ($this->config->get('ogone_mode') == 'test') {
			$this->data['action'] = $this->config->get('ogone_action_test');
		}
		
		$this->load->model('checkout/order');
		
		$order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);
		
		$data = array();
		
		$data['orderid'] = $order_info['order_id'];
		$data['pspid'] = $this->config->get('ogone_pspid');
		$data['currency'] = $order_info['currency_code'];
		
		$this->load->model('localisation/language');
		$language = $this->model_localisation_language->getLanguage($order_info['language_id']);
		$lanDetails = explode(',', $language['locale']);
		$data['language'] = $lanDetails[1];
		
		$total = $this->currency->convert($order_info['total'], $this->config->get('config_currency'), $order_info['currency_code']);
		$total = round($total, 2);
		$data['amount'] = ( string ) ($total * 100);
		
		// Customer info
		$data['cn'] = $order_info['payment_firstname'] . ' ' . $order_info['payment_lastname'];
		$data['email'] = $order_info['email'];
		$data['owneraddress'] = $order_info['payment_address_1'] . ' ' . $order_info['payment_address_2'];
		$data['ownerzip'] = $order_info['payment_postcode'];
		$data['ownertown'] = $order_info['payment_city'];
		$data['ownercty'] = $order_info['payment_iso_code_2'];
		$data['ownertelno'] = $order_info['telephone'];
		$data['title'] = $this->config->get('ogone_title');
		
		// Appearance on Ogone payment page
		$data['bgcolor'] = $this->config->get('ogone_bgcolor');
		$data['txtcolor'] = $this->config->get('ogone_txtcolor');
		$data['tblbgcolor'] = $this->config->get('ogone_tblbgcolor');
		$data['tbltxtcolor'] = $this->config->get('ogone_tbltxtcolor');
		$data['buttonbgcolor'] = $this->config->get('ogone_buttonbgcolor');
		$data['buttontxtcolor'] = $this->config->get('ogone_buttontxtcolor');
		$data['fonttype'] = $this->config->get('ogone_fonttype');
		
		// Sales or Authorization
		$data['operation'] = $this->config->get('ogone_transaction');
		
		// When the payment is captured, authorized or pending (STATUS 5, 51, 9 and 91)
		// the accept url is called by Ogone.
		$data['accepturl'] = $this->url->link('payment/ogone/callback');
		
		// The cancel, decline and exception url are all called in case of error conditions
		// during the payment.
		$data['cancelurl'] = $this->url->link('payment/ogone/callback');
		$data['declineurl'] = $this->url->link('payment/ogone/callback');
		$data['exceptionurl'] = $this->url->link('payment/ogone/callback');
		
		// On the Ogone page, these links are used when clicking on the Home or Catolog
		// buttons.
		$data['homeurl'] = $this->url->link('common/home');
		$data['catalogurl'] = $this->url->link('common/home');
		
		$data['shasign'] = $this->sha($data, 'in');
		
		$this->data['hidden'] = $data;
		
		if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/payment/ogone.tpl')) {
			$this->template = $this->config->get('config_template') . '/template/payment/ogone.tpl';
		} else {
			$this->template = 'default/template/payment/ogone.tpl';
		}
		
		$this->render();
	
	}
	
	public function callback() {
		
		if ($this->config->get('ogone_log')) {			
			$this->log->write(print_r($_GET, true));
		}
		
		$this->load->language('payment/ogone');
		
		$check = $this->sha($_GET, 'out');
		
		if ($check == $_GET['SHASIGN']) {
			
			$this->load->model('checkout/order');
			
			$statusCode = (int) $_GET['STATUS'];
			
			if ($_GET['NCERROR'] === '0') {
				// 
				switch ($statusCode) {
					case 9 : // Capture accepted
						$comment = $this->language->get('text_captured');
						$this->model_checkout_order->confirm($_GET['orderID'], $this->config->get('ogone_captured_status_id'), $comment, true);
						break;
					case 91 : // Capture pending
						$comment = $this->language->get('text_capture_waiting');
						$this->model_checkout_order->confirm($_GET['orderID'], $this->config->get('ogone_payment_processing_status_id'), $comment, true);
						break;
					case 5 : // Authorized
						$comment = $this->language->get('text_authorized');
						$this->model_checkout_order->confirm($_GET['orderID'], $this->config->get('ogone_authorized_status_id'), $comment, true);
						break;
					case 51 : // Authorization pending
						$comment = $this->language->get('text_authorization_waiting');
						$this->model_checkout_order->confirm($_GET['orderID'], $this->config->get('ogone_authorization_waiting_status_id'), $comment, true);
						break;
					default:
						$this->model_checkout_order->confirm($_GET['orderID'], $this->config->get('config_order_status_id'));
						break;
				}
				
				$this->redirect($this->url->link('checkout/success'));
			
			} else { 
				switch ($statusCode) {
					case 0 : // payment entry not completed
					case 1 : // cancelled by user
					case 2 : // not authorized (number of tries exceeds payment retry setting)
						// Don't confirm the order!!
						// Transaction retry is possible, therefore return to cart.
						// Please note that in case of status 2, the transaction has been refused by Ogone.
						// This will be visible in the transaction overview in the Ogone management application. 
						// If you were to resend the the same transaction details, it would be automatically refused by Ogone, even
						// if you entered proper payment details.
						// However, opencart 1.5.x generates a new orderID on checkout confirm, so no harm in resubmitting. 
						$this->redirect($this->url->link('checkout/cart'));
						break;
					case 52 :
					case 92 :
						// In both cases 52 and 92 Ogone recommends not reprocessing the transaction, becos it could result in double payment
						// Therefore we are confirming the order.
						$comment = $this->language->get('text_payment_result_uncertain');
						$this->model_checkout_order->confirm($_GET['orderID'], $this->config->get('config_order_status_id'), $comment, true);
						$this->redirect($this->url->link('checkout/success'));
						break;
				}		
			}
		
		} else { 
			trigger_error('SHA-OUT verification failed', E_USER_WARNING);
			$this->redirect($this->url->link('checkout/cart'));
		}
	}
	
	private function sha($data, $direction) {
		
		if (strlen(trim($direction)) == 0) {
			trigger_error("Ogone passphrase $direction not set", E_USER_ERROR);
		} 
		
		if ($direction == 'in') {
			$passphrase = $this->config->get('ogone_passphrase_in');
		} else {
			
			// Exclude following fields for hash generation.
			if (isset($data['route'])) {
				unset($data['route']);
			}
			
			if (isset($data['SHASIGN'])) {
				unset($data['SHASIGN']);
			}
			
			$passphrase = $this->config->get('ogone_passphrase_out');
		}
		
		$data = array_change_key_case($data, CASE_UPPER);
		ksort($data, SORT_STRING);
		
		$subj = '';
		foreach ( $data as $key => $value ) {
			if (strlen($value) !== 0) {
				$subj .= sprintf('%s=%s%s', $key, $value, $passphrase);
			}
		}
		
		$method = str_replace('-', '', $this->config->get('ogone_sha_method'));
		
		$sha = strtoupper(hash($method, $subj));
		
		if ($this->config->get('ogone_log')) {
			$this->log->write("SHA-{$direction} Subject: {$subj}");
			$this->log->write("$method result: $sha");
		}
		
		return $sha;
		
	}

}
